package com.xiangying.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisUtils {
	private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);
	
	public static int DEFAULT_EXPIRE = 3600;
	
	private static JedisPool jedisPool;

	private RedisUtils() {
		
	}
	
	static {
		jedisPool = (JedisPool)SpringUtils.getBean("jedisPool");
	}
	
	public static int getDefaultExpireTime(){
		return DEFAULT_EXPIRE * 30;
	}
	
	public static int getInvestRankingExpireTime(){
		return DEFAULT_EXPIRE * 60;
	}

	/**
	 * 设值
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean setRedis(String key, String value) {
		boolean ok = true;
		Jedis jedis = null;
		try {
			jedis = getJedisInstance();
			if (StringUtils.isBlank(key)) {
				ok = false;
			} else {
				jedis.set(key, value);
			}
		} catch (Exception e) {
			returnBrokenResource(jedis);
			logger.error("existsKey异常：", e);
			ok = false;
		} finally {
			returnResource(jedis);
		}
		return ok;
	}

	public static boolean setRedis(String key, String value, int timeout) {
		boolean ok = true;
		Jedis jedis = null;
		try {
			jedis = getJedisInstance();
			if (StringUtils.isBlank(key)) {
				ok = false;
			} else {
				jedis.set(key, value);
				jedis.expire(key, timeout);
			}
		} catch (Exception e) {
			returnBrokenResource(jedis);
			e.printStackTrace();
			logger.error("existsKey异常：", e);
			ok = false;
		} finally {
			returnResource(jedis);
		}
		return ok;
	}

	public static boolean setRedisNotime(String key, String value) {
		boolean ok = true;
		Jedis jedis =null;
		try {
			 jedis = getJedisInstance();
			 if (key.contains("null")) {
				 ok= false;
			 }else {
				String returnString=jedis.set(key, value);
				logger.info(key+":setRedisNotime-插入:"+returnString);
			}
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
			e.printStackTrace();
			ok = false;
		} finally {
			returnResource(jedis);
		}
		return ok;
	}
	
	public static boolean setRedisObj(String key, Object value) {
		boolean ok = true;
		Jedis jedis = null;
		try {
			if (StringUtils.isBlank(key)) {
				ok = false;
			} else {
				jedis = getJedisInstance();
				jedis.set(key.getBytes(), SerializeUtil.serialize(value));
			}
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
			ok = false;
		} finally {
			returnResource(jedis);
		}
		return ok;
	}

	public static boolean setRedisObj(String key, Object value, int timeout) {
		boolean ok = true;
		Jedis jedis = null;
		try {
			if (StringUtils.isBlank(key)) {
				ok = false;
			} else {
				jedis = getJedisInstance();
				jedis.set(key.getBytes(), SerializeUtil.serialize(value));
				jedis.expire(key, timeout);
			}
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
			ok = false;
		} finally {
			returnResource(jedis);
		}
		return ok;
	}
	
	/***
	 * 获取值
	 * 
	 * @param key
	 * @return
	 */
	public static String getRedis(String key) {
		String msg = null;
		Jedis jedis = null;
		if(StringUtils.isBlank(key)){
			return msg;
		}
		try {
			jedis = getJedisInstance();
			if (jedis.exists(key) && !key.contains("null")) {
				msg = jedis.get(key);
			}
			//LOGGER.info(key + ":redis-weixin-获取数据:" + msg);
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
		} finally {
			returnResource(jedis);
		}
		return msg;
	}

	public static String getRedis(String key, int timeout) {
		String msg = null;
		Jedis jedis = null;
		if(StringUtils.isBlank(key)){
			return msg;
		}
		try {
			jedis = getJedisInstance();
			if (jedis.exists(key) && !key.contains("null")) {
				msg = jedis.get(key);
				jedis.expire(key, timeout);
			}
			logger.info(key + ":getRedis-获取数据:" + msg);
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
		} finally {
			returnResource(jedis);
		}
		return msg;
	}

	/**
	 * 
	 * 获取一个对象
	 * 
	 * @param key
	 * @return
	 */
	public static Object getRedisObj(String key) {
		Object msg = null;
		Jedis jedis = null;
		if(StringUtils.isBlank(key)){
			return msg;
		}
		try {
			jedis = getJedisInstance();

			if (jedis.exists(key.getBytes()) && !key.contains("null")) {
				byte[] data100 = jedis.get(key.getBytes());
				msg = SerializeUtil.unserialize(data100);
				//jedis.expire(key.getBytes(), getDefaultExpireTime());
			}
			logger.info(key + ":getRedisObj-获取数据:" + msg);
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
		} finally {
			returnResource(jedis);
		}
		return msg;
	}

	public static Object getRedisObj(String key, int timeout) {
		Object msg = null;
		Jedis jedis = null;
		if(StringUtils.isBlank(key)){
			return msg;
		}
		try {
			jedis = getJedisInstance();

			if (jedis.exists(key.getBytes()) && !key.contains("null")) {
				byte[] data100 = jedis.get(key.getBytes());
				msg = SerializeUtil.unserialize(data100);
				jedis.expire(key.getBytes(), timeout);
			}
		} catch (Exception e) {
			returnBrokenResource(jedis);
			logger.error("existsKey异常：", e);
		} finally {
			returnResource(jedis);
		}
		return msg;
	}
	
	public static Object getRedisObjSecond(String key, int timeout) {
		Object msg = null;
		Jedis jedis = null;
		if(StringUtils.isBlank(key)){
			return msg;
		}
		try {
			jedis = getJedisInstance();

			if (jedis.exists(key.getBytes()) && !key.contains("null")) {
				byte[] data100 = jedis.get(key.getBytes());
				msg = SerializeUtil.unserialize(data100);
				jedis.expire(key.getBytes(), timeout);
			}
		} catch (Exception e) {
			returnBrokenResource(jedis);
			logger.error("existsKey异常：", e);
		} finally {
			returnResource(jedis);
		}
		return msg;
	}
	
	/**
	 * 判断存不存在
	 * 
	 * @param key
	 * @return
	 */
	public static boolean existsKey(String key) {
		boolean exists = true;
		Jedis jedis = null;
		try {
			if (StringUtils.isBlank(key)) {
				return false;
			}
			jedis = getJedisInstance();
			if(jedis == null) {
				exists = false;
			}
			exists = jedis.exists(key);
		} catch (Exception e) {
			logger.error("existsKey异常：", e);
			returnBrokenResource(jedis);
			return false;
		} finally {
			returnResource(jedis);
		}
		return exists;
	}

	/**
	 * 删除
	 * 
	 * @param key
	 * @return
	 */
	public static boolean deleteKey(String key) {
		boolean exists = true;
		Jedis jedis = null;
		try {
			jedis = getJedisInstance();
			if (jedis.exists(key)) {
				jedis.del(key);
			}
		} catch (Exception e) {
			logger.error("deletebatch异常：", e);
			exists = false;
			returnBrokenResource(jedis);
		} finally {
			returnResource(jedis);
		}
		return exists;
	}

	/**
	 * 批量删除
	 * 
	 * @param key
	 * @return
	 */
	public static boolean deletebatch(String key) {
		boolean exists = true;
		Jedis jedis = null;
		if(StringUtils.isBlank(key)){
			exists=false;
			return exists;
		}
		try {
			jedis = getJedisInstance();
			Set<String> set = jedis.keys(key + "*");
			for (String item : set) {
				jedis.del(item);
			}
		} catch (Exception e) {
			logger.error("deletebatch异常：", e);
			exists = false;
			returnBrokenResource(jedis);
		} finally {
			if(jedis!=null){
				returnResource(jedis);
			}
		}
		return exists;
	}

	public static Jedis getJedisInstance() {
		try {
			if (jedisPool != null) {
				Jedis resource = jedisPool.getResource();
				return resource;
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据下标选择库
	 * @param dbIndex
	 * @return
	 */
	public static Jedis getJedisInstance(final int dbIndex) {
		try {
			if (jedisPool != null) {
				Jedis resource = jedisPool.getResource();
				resource.select(dbIndex);
				return resource;
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("deprecation")
	public static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}

	@SuppressWarnings("deprecation")
	public static void returnBrokenResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnBrokenResource(jedis);
		}
	}
	
	public static class SerializeUtil {
		public static byte[] serialize(Object object) {
			ObjectOutputStream oos = null;
			ByteArrayOutputStream baos = null;
			try {
				// 序列化
				baos = new ByteArrayOutputStream();
				oos = new ObjectOutputStream(baos);
				oos.writeObject(object);
				byte[] bytes = baos.toByteArray();
				return bytes;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}

		public static Object unserialize(byte[] bytes) {
			if (bytes == null)
				return null;
			ByteArrayInputStream bais = null;
			try {
				// 反序列化
				bais = new ByteArrayInputStream(bytes);
				ObjectInputStream ois = new ObjectInputStream(bais);
				return ois.readObject();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}
}
